import config from "@/config";

// 全局socket
let socket = null;
// 连接状态
let isConnected = false;
// 当前重连次数
let reconnectCount = 0; 
// 最大重连次数
const MAX_RECONNECT_COUNT = 5; 
// 重连间隔（毫秒）
const RECONNECT_INTERVAL = 5000; 
// 重连定时器
let reconnectTimer = null; 
// 是否正在重连
let isReconnecting = false; 

// 初始化WebSocket
export function initWebSocket(uid, isReconnect = false) {
    return new Promise((resolve, reject) => {
        // 如果已有连接，先关闭
        if (socket) {
            closeWebSocket();
        }

        // 如果是重连，检查重连次数
        if (isReconnect) {
            console.log(`WebSocket第${reconnectCount}次重连尝试`);
        } else {
            // 新连接，重置重连计数
            reconnectCount = 0;
        }

        // 创建WebSocket连接
        socket = uni.connectSocket({
            url: config.wsUrl,
            success: (res) => {
                // 这里只是创建了连接对象，并不代表真正的连接成功
            },
            fail: (err) => {
                console.error('WebSocket连接创建失败', err);
                // 移除自动重连
                reject(err);
            }
        });

        // 添加 onOpen 监听器
        socket.onOpen(() => {
            console.log('WebSocket连接已打开，状态为 OPEN');
            // clearTimeout(connectionTimeout); // 移除超时定时器清除
            isConnected = true;
            isReconnecting = false;
            if (reconnectTimer) {
                clearTimeout(reconnectTimer);
                reconnectTimer = null;
            }
            sendHeartbeatMessage(uid);
            resolve(socket);
        });
        
        // 监听连接关闭
        socket.onClose(() => {
            console.log('WebSocket连接已关闭');
            isConnected = false;
        });
        
        // 监听错误
        socket.onError((err) => {
            console.error('WebSocket连接错误', err);
            isConnected = false;
            if (!isReconnect) {
                reject(err);
            }
        });
        
        // 监听消息
        socket.onMessage((res) => {
            console.log('收到WebSocket消息', res);
            // 解析消息
            let data = JSON.parse(res.data)
            // 消息类型
            let type = data.type;
            // 根据不同的消息类型做不同处理
            switch (type) {
                case 'heartbeat':
                    // 心跳消息已经由定时任务维护，这里不做处理
                    break;
                case 'timeout':
                    // 超时断开，尝试重连 - 只在这里重连
                    scheduleReconnect(uid);
                    break;
                case 'error':
                    console.error('定位失败：', data, JSON.stringify(data));
                    // 错误消息，用于后端返回错误信息，前端对应做错误处理，无实质性逻辑
                    break;
                case 'pull_location':
                    // TODO: 收到用户的坐标信息，前端对应做坐标显示处理
                    console.log('收到用户的坐标信息：', data, JSON.stringify(data));
                    uni.$emit('locationsMessagesChanged', data.message.locations);
                    // 触发全局事件
                    

                    break;
                case 'text':
                    console.log('文本信息', data, JSON.stringify(data));
                    uni.$emit('textMessagesChanged', data.message);
                    // TODO: 收到文本消息，前端对应做文本消息显示处理
                    break;
                default:
                    break;
            }
        });
    });
}

/**
 * 重连调度函数 - 只在收到timeout消息时调用
 */
export function scheduleReconnect(uid) {
    // 如果正在重连，或者重连次数大于等于最大重连次数，则不进行重连
    if (isReconnecting || reconnectCount >= MAX_RECONNECT_COUNT) {
        if (reconnectCount >= MAX_RECONNECT_COUNT) {
            console.error(`已达到最大重连次数 ${MAX_RECONNECT_COUNT}，停止重连`);
        }
        return;
    }
    
    // 设置正在重连
    isReconnecting = true;
    // 递增重连次数
    reconnectCount++;

    console.log(`${RECONNECT_INTERVAL}ms后进行第${reconnectCount}次重连`);
    
    // 设置重连定时器
    reconnectTimer = setTimeout(() => {
        console.log('开始执行重连...');
        initWebSocket(uid, true).catch(err => {
            console.error('重连失败:', err);
            // 重连失败后，重置重连状态，允许下次重连
            isReconnecting = false;
        });
    }, RECONNECT_INTERVAL);
}

/**
 * 发送消息基础方法，所有消息都通过这个方法发送
 * @param {*} type 消息类型 心跳消息：heartbeat，文本消息：text，错误消息：error，超时断开：timeout，推送坐标：push_location，拉取坐标：pull_location
 * @param {*} message 消息内容 根据不同业务传递不同格式的数据，与后端约定
 * @returns 
 */
export function sendMessage(type, message) {
    return new Promise((resolve, reject) => {
        // 检查连接状态
        if (!isWebSocketConnected()) {
            // console.error('WebSocket未连接');
            return;
        }
        try {
            // 定义数据格式
            const data = JSON.stringify({
                type: type,
                message: message
            });
            // 发送消息
            socket.send({
                data: data,
                success: () => {
                    // console.log('消息发送成功');
                    resolve();
                },
                fail: (err) => {
                    // console.error('消息发送失败', err);
                    reject(err);
                }
            });
        } catch (error) {
            console.error('发送消息时出错', error);
            reject(error);
        }
    });
}

// 检查连接状态
export function isWebSocketConnected() {
    return isConnected && socket;
}

// 关闭连接
export function closeWebSocket() {
    if (socket) {
        socket.close();
        socket = null;
        isConnected = false;
    }
    // 清理重连相关状态
    isReconnecting = false;
    if (reconnectTimer) {
        clearTimeout(reconnectTimer);
        reconnectTimer = null;
    }
}

/**
 * 发送心跳消息
 * 数据格式：{"type":"heartbeat","message":{"from_uid":"发送者ID","to_uid":0,"line_id":0,"message_type":"text","message_content":"ping"}}
 * @param {*} uid 发送者ID
 */
export function sendHeartbeatMessage(uid) {
    sendMessage('heartbeat', {
        from_uid: uid,
        to_uid: 0,
        line_id: 0,
        message_type: 'text',
        message_content: 'ping'
    })
}

/** 
 * 推送坐标
 * fix: 数据格式：{"type":"push_location","message":{"from_uid":"发送者ID","phone":"手机号","avatar":"头像","longitude":"经度","latitude":"纬度"}}
*/
export function pushLocation(uid, phone, avatar, longitude, latitude) {
    sendMessage('push_location', {
        from_uid: uid,
        phone: phone,
        avatar: avatar,
        longitude: longitude,
        latitude: latitude
    })
}

/**
 * 拉取坐标
 * 传递数据格式：{"type":"pull_location","message":{"uids":["用户id1","用户id2","用户id3"]}}
 * 返回数据格式：{"type":"pull_location","message":{"locations":[{"id":4,"longitude":"104.043263","latitude":"30.641896"},{"id":5,"longitude":"","latitude":""}]}}
 */
export function pullLocation(uids) {
    sendMessage('pull_location', {
        uids: uids
    })
}

/**
 * 发送文本消息
 * 传递数据格式：{"type":"text","message":{"from_uid":"发送者ID","to_uid":接收者ID,"line_id":线路ID,"message_type":"text","message_content":"消息内容"}}
 */
export function sendTextMessage(from_uid, to_uid, line_id, message_content, message_type = 'text') {
    sendMessage('text', {
        from_uid: from_uid,
        to_uid: to_uid,
        line_id: line_id,
        message_type: message_type,
        message_content: message_content
    })
}

/**
 * 获取socket对象
 * @returns 
 */
export function getSocket() {
    return socket
}
